package com.tuniu.agents.impl.hotel;

import com.tuniu.agents.agent.AgentManagerGroup;
import com.tuniu.agents.common.agent.Recommender;
import com.tuniu.agents.common.handler.HotelStreamResponseHandler;
import com.tuniu.agents.common.handler.IStreamResponseHandler;
import com.tuniu.agents.common.i18n.I18nConstants;
import com.tuniu.agents.common.message.BaseAgentNewResp;
import com.tuniu.agents.tools.hotel.utils.HotelCommonUtil;
import com.tuniu.agents.util.I18nUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import reactor.core.publisher.Flux;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Hotel recommendation agent that handles hotel related queries and responses
 */
@Slf4j
public class HotelRecommender extends Recommender {

    /**
     * Constructor with base parameters
     * 
     * @param agentManagerGroup agent manager group
     * @param agentId agent identifier
     * @param promptTemplateId prompt template identifier
     */
    public HotelRecommender(AgentManagerGroup agentManagerGroup, String agentId, String promptTemplateId) {
        super(agentManagerGroup, agentId, promptTemplateId);
    }

    /**
     * Constructor with stream response handler
     * 
     * @param agentManagerGroup agent manager group
     * @param agentId agent identifier
     * @param promptTemplateId prompt template identifier
     * @param streamResponseHandler handler for stream responses
     */
    public HotelRecommender(AgentManagerGroup agentManagerGroup, String agentId, String promptTemplateId, IStreamResponseHandler streamResponseHandler) {
        super(agentManagerGroup, agentId, promptTemplateId, streamResponseHandler, false, false);
    }

    @Override
    public Flux<String> stream(String conversationId, List<Message> messages, Map<String, Object> context) {
        String message = messages.get(0).getText();
        if (StringUtils.isBlank(message) && "null".equals(message)) {
            log.error("HotelRecommender stream  error,message=null");
            return Flux.just(BaseAgentNewResp.sendAnswerMsg(null, I18nUtil.getMessage(conversationId,I18nConstants.COMMON_SYSTEM_ERROR_MESSAGE_KEY)));
        }

        StringBuilder hotelMarkdown = new StringBuilder();
        try {
            String lastAction = (String) chatEnvironmentMemory.get(conversationId, conversationId + "_LAST_ACTION");
            if ("package_query".equals(lastAction)) {
                HotelCommonUtil.buildPkgHotelMarkdwon(message, hotelMarkdown);
            } else if ("nearby_hotel_query".equals(lastAction)) {
                HotelCommonUtil.buildPoiHotelMarkdown(message, hotelMarkdown);
            }
        } catch (Exception e) {
            log.error("Error processing hotel markdown! message:{}", message, e);
        }

        Flux<String> flux = this.chatClientRequestSpec(conversationId, List.of(new UserMessage(hotelMarkdown.toString())), context).stream().content();
        Map<String, Object> params = Map.of(HotelStreamResponseHandler.MESSAGE, message,
                HotelStreamResponseHandler.CONVERSATION_ID, conversationId);
        return streamResponseHandler == null ? flux : streamResponseHandler.handle(params, flux);
    }
}
